package com.scpii.universal.pns.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.xwork.StringUtils;
import org.springframework.stereotype.Service;

import com.scpii.universal.constant.GenericConstants;
import com.scpii.universal.dto.AttributeDto;
import com.scpii.universal.dto.UserInfoDto;
import com.scpii.universal.hibernate.dao.AttributeDao;
import com.scpii.universal.hibernate.dao.AttributeValueDao;
import com.scpii.universal.hibernate.dao.ContentDao;
import com.scpii.universal.hibernate.entity.AttributeTab;
import com.scpii.universal.hibernate.entity.AttributeValueTab;
import com.scpii.universal.hibernate.entity.ContentTab;
import com.scpii.universal.pns.dao.EcProductDao;
import com.scpii.universal.pns.dao.ResourcesDao;
import com.scpii.universal.pns.dto.EcProductDto;
import com.scpii.universal.pns.dto.ProductCotent;
import com.scpii.universal.pns.entity.EcProduct;
import com.scpii.universal.pns.entity.Resources;
import com.scpii.universal.service.AppContentService;

@Service
public class EcProductServiceImpl extends PnsBaseServiceImpl<EcProduct, Long>
		implements EcProductService {
	@Resource
	private EcProductDao ecProductDao;
	@Resource
	private AttributeDao attributeDao;
	@Resource
	private AttributeValueDao attributeValueDao;
	@Resource
	private ContentDao contentDao;
	@Resource
	private ResourcesDao resourcesDao;
	@Resource
	private AppContentService appContentService;
	private static final SimpleDateFormat sdf = new SimpleDateFormat(
			GenericConstants.DATE_FORMAT);

	@Resource
	public void setBaseDao(EcProductDao ecProductDao) {
		super.setBaseDao(ecProductDao);
	}

	@Override
	public void saveProduct(EcProductDto ecProductDto,
			List<AttributeDto> attList, UserInfoDto user) {
		Date date = new Date();
		EcProduct ecProduct = ecProductDto.getEcProduct();
		ecProduct.setColumnAlias(populateColumnAlias(ecProductDto));
		ecProduct.setBody(populateProductBody(ecProductDto));
		ecProduct.setThumbImage(ecProduct.getThumbImage().replace(
				getServerUrl(), ""));
		ecProduct.setGiveUserPoints(ecProduct.getGiveUserPoints() == null ? 0
				: ecProduct.getGiveUserPoints());
		ecProduct.setListPrice(ecProduct.getListPrice() == null ? ecProduct
				.getPrice() : ecProduct.getListPrice());
		if (ecProduct.getId() != null) {
			ecProduct.setUpdateDt(date);
			ecProductDao.update(ecProduct);
		} else {
			ecProduct.setCatId(ecProductDto.getIntCateId());
			ecProduct.setAppId(GenericConstants.APP_ID_PRE + user.getAppId());
			ecProduct.setPublish(true);
			ecProduct.setSortOrders((short) 0);
			ecProduct.setRatingAvg(0d);
			ecProduct.setCreateDt(date);
			ecProduct.setUpdateDt(date);
			ecProduct.setReviewsCount(0l);
			ecProduct.setOrderCount(0l);
			ecProduct.setFavCount(0l);
			ecProduct.setCommentCount(0l);
			ecProductDao.save(ecProduct);
		}
		Integer contentId = saveOrUpdateContent(ecProductDto, user);
		saveOrUpdateAttr(attList, contentId);
		saveResources(ecProductDto);
		deleteResources(ecProductDto.getDeletedViewImg());
	}

	private String populateProductBody(EcProductDto ecProductDto) {
		JSONArray datas = new JSONArray();
		List<ProductCotent> contents = ecProductDto.getContents();
		if (contents == null || contents.size() <= 0)
			return null;
		for (ProductCotent productCotent : contents) {
			if (productCotent == null
					|| StringUtils.isBlank(productCotent.getValue()))
				continue;
			JSONObject data = new JSONObject();
			data.put("type", productCotent.getType());
			if ("IMAGE".equals(productCotent.getType())) {
				productCotent.setValue(productCotent.getValue().replace(
						getServerUrl(), ""));
			}
			data.put("value", productCotent.getValue());
			datas.add(data);
		}
		return datas.toString();
	}

	private void deleteResources(String data) {
		if (StringUtils.isBlank(data))
			return;
		data = data.substring(0, data.length() - 1);
		String[] ids = data.split(",");
		for (String id : ids) {
			resourcesDao.delete(Long.parseLong(id));
		}
	}

	private void saveResources(EcProductDto ecProductDto) {
		List<Resources> lstResources = ecProductDto.getResources();
		Date date = new Date();
		if (lstResources != null && lstResources.size() > 0) {
			for (Resources resources : lstResources) {
				if (resources == null)
					continue;
				resources.setMediaUrl(resources.getMediaUrl().replace(
						getServerUrl(), ""));
				if (resources.getId() != null) {
					Resources oldRes = resourcesDao.get(resources.getId());
					oldRes.setThumbImage(resources.getMediaUrl());
					oldRes.setMediaUrl(resources.getMediaUrl());
					oldRes.setUpdateDt(date);
					resourcesDao.update(oldRes);
				} else {
					resources.setTargetId(ecProductDto.getEcProduct().getId());
					resources.setCreateDt(new Date());
					resources.setMediaType("IMAGE_LIST");
					resources.setThumbImage(resources.getMediaUrl());
					resources.setUpdateDt(date);
					resourcesDao.save(resources);
				}
			}
		}
	}

	private String populateColumnAlias(EcProductDto ecProductDto) {
		JSONObject data = new JSONObject();
		data.put("listPrice", ecProductDto.getListPriceName());
		data.put("price", ecProductDto.getPriceName());
		data.put("ratingAvg", ecProductDto.getRatingAvgName());
		data.put("reviewsCount", ecProductDto.getReviewsCountName());
		data.put("orderCount", ecProductDto.getOrderCountName());
		data.put("favCount", ecProductDto.getFavCountName());
		data.put("commentCount", ecProductDto.getCommentCountName());
		return data.toString();
	}

	private Integer saveOrUpdateContent(EcProductDto ecProductDto,
			UserInfoDto user) {
		String date = sdf.format(new Date());
		ContentTab content = null;
		if (ecProductDto.getIntContentId() != null) {
			content = contentDao.get(ecProductDto.getIntContentId());
			content.setVarContentName(ecProductDto.getEcProduct().getTitle());
			content.setVarContentImgUrl(ecProductDto.getEcProduct()
					.getThumbImage());
			content.setVarContentDescript(ecProductDto.getEcProduct()
					.getSummary());
			content.setDatUpdateDatetime(date);
			contentDao.update(content);
		} else {
			content = new ContentTab();
			content.setIntCateId(ecProductDto.getIntCateId().intValue());
			content.setIntAppId(user.getAppId());
			content.setIntDeleteSign(GenericConstants.DELETE_SIGN_EXIST);
			content.setIntEnterpId(user.getIntEnterpId());
			content.setIntSortOrder(0);
			content.setIntAction(0);
			content.setIntViewCount(0);
			content.setIntPrivilegeUser(0l);
			content.setDatUpdateDatetime(date);
			content.setDatAddDatetime(date);
			content.setVarContentName(ecProductDto.getEcProduct().getTitle());
			content.setVarContentImgUrl(ecProductDto.getEcProduct()
					.getThumbImage());
			content.setVarContentDescript(ecProductDto.getEcProduct()
					.getSummary());
			content.setIntResourceId(ecProductDto.getEcProduct().getId());
			content.setCommentCount(0);
			content.setFavCount(0);
			content.setJoinCount(0);
			contentDao.save(content);
		}
		return content.getIntContentId();
	}

	private void saveOrUpdateAttr(List<AttributeDto> attList, int contentId) {
		String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
				.format(new Date());
		if (attList != null && attList.size() > 0) {
			AttributeValueTab attributeValueTab = null;
			for (AttributeDto attributeDto : attList) {
				if (attributeDto.getIntAttriValueId() != null) {
					// update
					attributeValueTab = attributeValueDao.get(attributeDto
							.getIntAttriValueId());
				} else {
					// add
					attributeValueTab = new AttributeValueTab();
					attributeValueTab.setIntContentId(contentId);
					attributeValueTab.setIntAttriId(attributeDto
							.getIntAttriId());
					attributeValueTab
							.setIntDeleteSign(GenericConstants.DELETE_SIGN_EXIST);
				}
				attributeValueTab.setDatMudifyDate(date);

				AttributeTab attrTab = attributeDao.get(attributeDto
						.getIntAttriId());
				int inputType = attrTab.getIntInputType();
				if (inputType == GenericConstants.ATTRIBUTE_INPUT_TYPE_SELECT) {
					String attriListIds = attributeDto.getIntAttrListId();
					String[] values = new String[2];
					if (attriListIds != null
							&& attriListIds.trim().length() > 0) {
						values = attriListIds.split("#");
					}
					attributeValueTab.setIntAttrListId(values[0]);
					attributeValueTab.setVarAttriValue(values[1]);
				} else {
					attributeValueTab.setVarAttriValue(attributeDto
							.getVarAttriValue());
				}
				if (attributeDto.getIntAttriValueId() != null) {
					attributeValueDao.update(attributeValueTab);
				} else {
					attributeValueDao.save(attributeValueTab);
				}
			}
		}
	}

	@Override
	public Long getTotalCountByCateId(Long cateId, Long appId) {
		StringBuffer hql = new StringBuffer("from EcProduct e ");
		hql.append(" where e.catId=:catId ");
		hql.append(" and  e.publish=:publish ");
		hql.append(" and  e.appId=:appId ");
		Map<String, Object> argsMap = new HashMap<String, Object>();
		argsMap.put("publish", true);
		argsMap.put("appId", appId);
		argsMap.put("catId", cateId);
		List<EcProduct> products = ecProductDao.hqlGetList(hql.toString(),
				argsMap);
		if (products != null) {
			return (long) products.size();
		} else {
			return 0l;
		}
	}

	@Override
	public List<EcProductDto> getAllByCateId(Long cateId, Long appId,
			int pageNo, int pageSize) {
		StringBuffer hql = new StringBuffer("from EcProduct e ");
		hql.append(" where e.catId=:catId ");
		hql.append(" and  e.publish=:publish ");
		hql.append(" and  e.appId=:appId ");
		hql.append(" order by e.sortOrders desc,e.updateDt desc ");
		Map<String, Object> argsMap = new HashMap<String, Object>();
		argsMap.put("publish", true);
		argsMap.put("appId", appId);
		argsMap.put("catId", cateId);
		List<EcProduct> products = ecProductDao.findByHql(hql.toString(),
				pageNo, pageSize, argsMap);
		List<EcProductDto> results = new ArrayList<EcProductDto>();
		EcProductDto ecProductDto = null;
		for (EcProduct ecProduct : products) {
			ecProductDto = new EcProductDto();
			ecProductDto.setEcProduct(ecProduct);
			ecProductDto.setIntContentId(contentDao
					.getContentIdByResourceId(ecProduct.getId()));
			results.add(ecProductDto);
		}
		return results;
	}

	@Override
	public void deleteProduct(Long productId, int contentId, boolean isBinded) {
		StringBuffer hql = new StringBuffer("update EcProduct e set ");
		Map<String, Object> argsMap = new HashMap<String, Object>();
		hql.append(" e.publish=:publish");
		argsMap.put("publish", false);
		hql.append(" where e.id=:id");
		argsMap.put("id", productId);
		ecProductDao.hqlOperation(hql.toString(), argsMap);
		// resourcesDao.deleteByTargerId(productId);
		appContentService.deleteContentDetail(contentId, isBinded);
	}

	@Override
	public void topProductSortOrder(Long productId, Long cateId) {
		Short maxSortOrder = (short) (ecProductDao.getMaxSortOrder(cateId) + 1);
		updateOrder(productId, maxSortOrder);
	}

	private void updateOrder(Long productId, Short sortOrder) {
		StringBuffer hql = new StringBuffer("update EcProduct e set ");
		Map<String, Object> argsMap = new HashMap<String, Object>();
		hql.append(" e.sortOrders=:sortOrders");
		argsMap.put("sortOrders", sortOrder);
		hql.append(" where e.id=:id");
		argsMap.put("id", productId);
		ecProductDao.hqlOperation(hql.toString(), argsMap);
	}

	@Override
	public void cancelProductTop(Long productId) {
		updateOrder(productId, (short) 0);
	}

}
